<template>
	<div class="table-header" v-if="defaultTableOption.tableHeader">
		<slot name="table-header" />
	</div>

	<el-table
		v-loading="loading"
		ref="tableRef"
		class="basic-table"
		:data="data"
		:height="defaultTableOption.height"
		@row-click="rowClick"
		@selection-change="handleSelectionChange"
		:show-summary="showSummary"
		:summary-method="summaryMethod"
		:row-class-name="tableRowClassName"
	>
		<template #empty>
			<TableEmpty />
		</template>
		<template #append>
			<slot name="append"></slot>
		</template>
		<el-table-column
			v-if="defaultTableOption.selection"
			type="selection"
			width="55"
		/>
		<el-table-column
			v-if="defaultTableOption.index"
			:width="defaultTableOption.indexWidth"
			:align="defaultTableOption.column[0]?.align || 'center'"
			:label="defaultTableOption.indexLabel"
			type="index"
		/>
		<el-table-column
			v-for="tr in defaultTableOption.column"
			:key="tr.prop"
			:prop="tr.prop"
			:fixed="tr.fixed"
			:label="tr.label"
			:width="tr.width"
			:sortable="tr.sortable"
			:align="tr.align || 'center'"
			:show-overflow-tooltip="tr.overHidden"
			:min-width="100"
		>
			<template #header="{ column, $index }">
				<slot :name="tr.prop + '-header'" :column="column" :index="$index">
					{{ tr.i18n ? tr.i18n : tr.label }}
				</slot>
			</template>

			<template #default="{ row, column, $index }">
				<template v-if="tr.children && tr.children.length">
					<el-table-column
						v-for="trSeconde in tr.children"
						:key="trSeconde.prop"
						:prop="trSeconde.prop"
						:fixed="trSeconde.fixed"
						:label="trSeconde.label"
						:width="trSeconde.width"
						:sortable="tr.sortable"
						:align="trSeconde.align || 'center'"
						:show-overflow-tooltip="trSeconde.overHidden"
					>
						<template #header="{ column, $index }">
							<slot
								:name="trSeconde.prop + '-header'"
								:column="column"
								:index="$index"
							>
								{{ trSeconde.i18n ? trSeconde.i18n : trSeconde.label }}
							</slot>
						</template>
						<template #default="{ row, column, $index }">
							<slot
								:name="trSeconde.prop"
								:row="row"
								:column="column"
								:index="$index"
							>
								<div
									:class="trSeconde.overHidden ? 'tr-overflow' : ''"
									v-html="getContent(trSeconde, row)"
								/>
							</slot>
						</template>
					</el-table-column>
				</template>
				<template v-else>
					<slot :name="tr.prop" :row="row" :column="column" :index="$index">
						<div
							:class="tr.overHidden ? 'tr-overflow' : ''"
							v-html="getContent(tr, row)"
						/>
					</slot>
				</template>
			</template>
		</el-table-column>
		<el-table-column
			v-if="defaultTableOption.menu"
			fixed="right"
			align="center"
			:width="defaultTableOption.menuWidth"
			label="操作"
		>
			<template #default="{ row, $index }">
				<slot name="menu" :row="row" :index="$index" />
			</template>
		</el-table-column>
	</el-table>

	<div class="pagination" v-if="!defaultTableOption.hiddenPage">
		<el-pagination
			v-model:current-page="pagination.currentPage"
			v-model:page-size="pagination.pageSize"
			:page-sizes="pagination.pageSizes"
			:layout="pagination.layout"
			:total="pagination.total"
			:background="pagination.background"
			@size-change="sizeChange"
			@current-change="currentChange"
		/>
	</div>
</template>

<script setup lang="ts">
/**
 * 通用table封装 一级表头 暂不支持二级表头
 */
import { reactive, ref, watch, computed, shallowRef } from 'vue';
// import { useI18n } from "vue-i18n";
import TableEmpty from './components/TableEmpty.vue';

defineOptions({
	name: 'BasicTable',
});

// const i18n = useI18n();
const emits = defineEmits<{
	'row-click': [data: { row: any; column: any; event: Event }];
	'update:page': [data: BasicTableNameSpace.PageType];
	'current-change': [val: number];
	'size-change': [val: number];
	'selection-change': [val: any[]];
}>();

const props = withDefaults(
	defineProps<{
		data: any[];
		tableLoading?: boolean;
		page?: BasicTableNameSpace.PageType;
		option: BasicTableNameSpace.OptionType;
		showSummary?: boolean;
		summaryMethod?: any;
	}>(),
	{
		data: () => [],
		tableLoading: false,
		page: () => ({
			currentPage: 1,
			pageSize: 30,
			pageSizes: [10, 20, 30, 50],
			total: 0,
			layout: 'total, sizes, prev, pager, next, jumper',
		}),
		option: () => ({
			index: true,
			indexWidth: 80,
			indexLabel: '序号',
			tableHeader: true,
			menu: true,
			column: [],
		}),
		showSummary: false,
		summaryMethod: () => {},
	},
);

// tableOption
const tableRef = shallowRef();
const defaultTableOption = ref(
	Object.assign(
		{
			index: true,
			indexWidth: 80,
			indexLabel: '序号',
			tableHeader: false,
			menu: true,
			hiddenPage: false,
			selection: false,
		},
		props.option,
	),
);
watch(
	() => props.option,
	() => {
		defaultTableOption.value = Object.assign(
			{
				index: true,
				indexWidth: 80,
				indexLabel: '序号',
				tableHeader: true,
				menu: true,
				hiddenPage: false,
				selection: false,
			},
			props.option,
		);
	},
	{
		deep: true,
	},
);

// loading
const loading = ref(props.tableLoading || false);
watch(
	() => props.tableLoading,
	(val) => {
		loading.value = val;
	},
);
const tableRowClassName = ({ row }: { row: any }) => {
	if (row.active) {
		return 'active-row';
	}
	return '';
};

// 分页
const pagination = reactive({
	currentPage: props.page.currentPage || 1,
	pageSize: props.page.pageSize || 10,
	pageSizes: props.page.pageSizes || [10, 20, 30, 50],
	total: props.page.total || 0,
	layout: props.page.layout || 'total, sizes, prev, pager, next, jumper',
	background: props.page.background || false,
});

watch(
	() => props.page,
	(val) => {
		pagination.currentPage = val.currentPage || pagination.currentPage;
		pagination.pageSize = val.pageSize || pagination.pageSize;
		pagination.pageSizes = val.pageSizes || pagination.pageSizes;
		pagination.total = Number.isInteger(val.total)
			? val.total
			: pagination.total;
		pagination.layout = val.layout || pagination.layout;
		pagination.background = val.background || pagination.background;
	},
	{
		deep: true,
	},
);

const getContent = computed(() => {
	return (tr: BasicTableNameSpace.ColumnType, row: any) => {
		if (!row) return '-';

		if (tr.formatter) {
			return tr.formatter(row) || '-';
		}
		if (row[tr.prop] && row[tr.prop] !== '') {
			return row[tr.prop];
		} else {
			return '-';
		}
	};
});

function sizeChange(val: number) {
	emits('update:page', pagination);
	emits('size-change', val);
}
function currentChange(val: number) {
	emits('update:page', pagination);
	emits('current-change', val);
}

function rowClick(row: any, column: any, event: Event) {
	emits('row-click', {
		row,
		column,
		event,
	});
}
function handleSelectionChange(val: any) {
	emits('selection-change', val);
}
</script>

<style lang="scss">
.basic-table.el-table {
	th.el-table__cell {
		background-color: #f1f5f8;
		color: #333;
		font-weight: 400;
		line-height: 48px;
	}
	td.el-table__cell {
		color: #333;
		line-height: 48px;
	}
	.el-table__inner-wrapper::before {
		height: 5px;
	}
	.el-table__inner-wrapper {
		height: 100% !important;
	}
	.active-row {
		--el-table-tr-bg-color: #81d3f8;
	}
}
.table-head-box {
	display: flex;
	.table-head-item {
		display: flex;
		justify-content: space-between;
		align-items: center;
		min-width: 334px;
		padding: 15px 15px;
		margin-right: 15px;
		background: #f7f7f7;
		box-sizing: border-box;
		.num {
			font-family: Alimama ShuHeiTi;
			font-weight: bold;
			font-size: 30px;
			color: #333333;
		}
		.title {
			font-family: Source Han Sans CN;
			font-weight: 400;
			font-size: 16px;
			color: #666666;
		}
	}
}
.table-more-btns {
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	.el-button + .el-button {
		margin-left: 0px;
	}
}
</style>
<style scoped lang="scss">
.table-header {
	margin-bottom: 20px;
}

.pagination {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	margin-top: 20px;

	:deep(.el-pagination) {
		--el-pagination-font-size: 13px;
		--el-pagination-button-height: 28px;
		--el-pagination-button-width: 28px;
		--el-component-size: 28px;

		.el-select {
			width: 88px;
			.el-select__wrapper {
				min-height: 28px;
				font-size: 13px;
				padding-left: 8px;
				padding-right: 8px;
			}
		}

		.el-pagination__editor.el-input {
			width: 48px;
			font-size: 13px;
		}

		.el-pager li,
		.btn-prev,
		.btn-next {
			background-color: var(--el-color-white);
			border: 1px solid #dddddd;
			border-radius: 3px;
		}

		.el-pager li.is-active {
			background-color: var(--el-color-white) !important;
			color: var(--el-color-primary) !important;
			border: 1px solid var(--el-color-primary);
		}
	}
}

.tr-overflow {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
</style>
